#include "hifunction.h"
#include <sys/vfs.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sstream>
#include <string.h>
#include<fcntl.h>

string get_app_path()
{
    char abs_path[1024];
    int cnt = readlink("/proc/self/exe", abs_path, 1024);//获取可执行程序的绝对路径
    if(cnt < 0|| cnt >= 1024)
    {
        return NULL;
    }

    //最后一个'/' 后面是可执行程序名，去掉devel/lib/m100/exe，只保留前面部分路径
    for(int i = cnt; i >= 0; --i)
    {
        if(abs_path[i]=='/')
        {
            abs_path[i + 1]='\0';
            break;
        }
    }

    string path(abs_path);    
    return path;
}

void mkdirs(const char *muldir)
{
    int i,len;
    char str[512];
    strncpy(str, muldir, 512);
    len=strlen(str);
    for( i=0; i<len; i++ )
    {
        if( str[i]=='/' )
        {
            str[i] = '\0';
            if( access(str,0)!=0 )
            {
                mkdir( str, 0777 );
            }
            str[i]='/';
        }
    }
    if( len>0 && access(str,0)!=0 )
    {
        mkdir( str, 0777 );
    }
    return;
}

bool is_file_exits(const char* path)
{
    if(0 == access(path, F_OK)) {
        return true;
    }
    return false;
}

int get_disk_free_mb(char* dir)
{
    if(dir == NULL) return 0;

    struct statfs diskInfo;

    statfs(dir, &diskInfo);

    unsigned long long blocksize = diskInfo.f_bsize;    //每个block里包含的字节数
    unsigned long long freeDisk = diskInfo.f_bfree * blocksize; //剩余空间的大小
    unsigned long long availableDisk = diskInfo.f_bavail * blocksize;   //可用空间大小
    printf("Disk_free = %llu MB = %llu GB\nDisk_available = %llu MB = %llu GB\n",
        freeDisk/(1024*1024), freeDisk>>30, availableDisk>>20, availableDisk>>30);

    return freeDisk >> 20;
}

bool remove_dir(string dirName)
{
    return true;
}

void confirm_enough_freespace(char* dir)
{
    int space;
    space = (int)(get_disk_total_mb(dir) * 0.95);

    char buffer[128];
    sprintf(buffer, "/nand/boot/delete %d &", space);
    printf("=== confirmEnoughFreeDisk()     %s  \n", buffer);
    system(buffer);
}

bool have_enough_freespace(char* dir)
{
    confirm_enough_freespace(dir);
    if (get_disk_free_mb(dir) < 5 * 1024)
        return false;

    return true;
}

bool check_disk_space(char *dir, unsigned int reserved_space_mb)
{
    char buffer[128];
    unsigned int totoal_space = get_disk_total_mb(dir);
    sprintf(buffer, "/nand/boot/delete %d &", totoal_space-reserved_space_mb);
    printf("=== confirmEnoughFreeDisk()     %s  \n", buffer);
    system(buffer);

    if (get_disk_free_mb(dir) < 5 * 1024)
        return false;

    return true;
}

string get_format_time()
{
    //格式: yyyy_MM_dd_hh_mm
    time_t timep;
    struct tm *p = NULL;
    time(&timep);
    p=localtime(&timep);

    char str[64];
    memset(str, 0, sizeof(str));
    sprintf(str, "%.4d_%.2d_%.2d_%.2d_%.2d",
           1900+p->tm_year,
           p->tm_mon+1,
           p->tm_mday,
           p->tm_hour,
           p->tm_min
           );
    return string(str);
}

int proc_shell_cmd(char *cmd, char result[])
{
    char tmpbuf[1024] = {0};
    FILE *fp = NULL;

    if( (fp = popen(cmd, "r")) == NULL ) {
        printf("popen error! cmd: %s\n", cmd);
        return -1;
    }

   while (fgets(tmpbuf, sizeof(tmpbuf), fp)) {
       printf("tmpbuf: %s\n", tmpbuf);
       strcat(result, tmpbuf);
   }
    pclose(fp);    
    return 0;
}

int get_cpu_info(char *path, char *name, char infor[])
{
    int fd = open(path, O_RDONLY);
    char store[2000];
    int k = 0;
    char *p = NULL;

    read(fd, store, sizeof(store));
    close(fd);
    //get point of the row
    p = strstr(store, name);

    //skip title
    do
    {
        p++;
    } while (*p != ':');
    p += 2;
    //get number
    while (*p != '\n')
    {
        infor[k] = *p;
        k++;
        p++;
    }
    infor[k] = '\0';
}

int get_uboot_info(char uboot_info[])
{
    proc_shell_cmd("cat /proc/version", uboot_info);
}

void get_disk_space_info(char* dir, unsigned long &total_space, unsigned long &free_space, unsigned long &available_space)
{
    if(dir == NULL)
        return;

    struct statfs diskInfo;

    statfs(dir, &diskInfo);

    //每个block里包含的字节数
    unsigned long long blocksize = diskInfo.f_bsize;
    //剩余空间的大小
    unsigned long long freeDisk = diskInfo.f_bfree * blocksize;
    //可用空间大小
    unsigned long long availableDisk = diskInfo.f_bavail * blocksize;

    total_space = diskInfo.f_blocks*blocksize>>30;
    free_space = freeDisk>>30;//GB
    available_space = availableDisk>>30;
}

int get_disk_total_mb(char *dir)
{
    if(dir == NULL) return 0;

    struct statfs diskInfo;

    statfs(dir, &diskInfo);

    unsigned long long blocksize = diskInfo.f_bsize;    //每个block里包含的字节数
    unsigned long long total_mb = diskInfo.f_blocks*blocksize;
    return total_mb >> 20;
}

unsigned char to_hex(unsigned char x)
{ 
    return  x > 9 ? x + 55 : x + 48; 
}

string http_url_encode(const string& str)
{//转换为application/x-www-form-urlencoded MIME 格式
    std::string strTemp = "";
    size_t length = str.length();
    for (size_t i = 0; i < length; i++)
    {
        if (isalnum((unsigned char)str[i]) || 
            (str[i] == '-') ||
            (str[i] == '_') || 
            (str[i] == '.') || 
            (str[i] == '~'))
            strTemp += str[i];
        else if (str[i] == ' ')
            strTemp += "+";
        else
        {
            strTemp += '%';
            strTemp += to_hex((unsigned char)str[i] >> 4);
            strTemp += to_hex((unsigned char)str[i] % 16);
        }
    }
    return strTemp;
}


